/**
 * 
 */
package org.mspring.mlog.service.security.impl;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.mspring.mlog.entity.security.Role;
import org.mspring.mlog.entity.security.User;
import org.mspring.mlog.entity.security.UserRole;
import org.mspring.mlog.entity.security.UserRolePK;
import org.mspring.mlog.service.security.UserService;
import org.mspring.platform.dao.hibernate.GenericDao;
import org.mspring.platform.dao.hibernate.common.EnhancedRule;
import org.mspring.platform.utils.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author Gao Youbo
 * @since 2012-7-12
 * @Description
 * @TODO
 */
@Service
@Transactional
public class UserServiceImpl extends GenericDao<User, Long> implements UserService {

    private static final Logger log = Logger.getLogger(UserServiceImpl.class);

    @Override
    public User validateUser(String username, String password) {
        // TODO Auto-generated method stub
        return uniqueResult("select u from User u where u.name = ? and u.password = ?", username, StringUtils.getMD5(password));
    }

    @Override
    public User validateUserWithoutMD5(String username, String password) {
        // TODO Auto-generated method stub
        return uniqueResult("select u from User u where u.name = ? and u.password = ?", username, password);
    }

    @Override
    public User getUserByName(String username) {
        // TODO Auto-generated method stub
        return (User) getSession().createQuery("select user from User user where user.name = ?").setString(0, username).setCacheable(true).setCacheRegion(User.class.getName()).uniqueResult();
    }

    @Override
    public User createUser(User user) {
        // TODO Auto-generated method stub
        user.setCreateTime(new Date());
        user.setPassword(StringUtils.getMD5(user.getPassword()));
        return super.save(user);
    }

    @Override
    public void deleteUser(Long id) {
        // TODO Auto-generated method stub
        // 删除用户对应的信息
        executeUpdate("delete UserRole userRole where userRole.PK.user.id = ?", id);
        executeUpdate("delete Post post where post.author.id = ?", id);
        executeUpdate("delete PostCatalog postCatalog where postCatalog.user.id = ?", id);
        executeUpdate("delete Comment comment where comment.author.id = ?", id);

        // 删除用户
        super.remove(id);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Role> getUserRoles(Long userId) {
        // TODO Auto-generated method stub
        return getHibernateTemplate().list("select userRole.PK.role from UserRole userRole where userRole.PK.user.id = ?", userId);
    }

    @Override
    public void setUserRoles(Long user, Serializable... roles) {
        // TODO Auto-generated method stub
        executeUpdate("delete from UserRole userRole where userRole.PK.user.id = ?", user);
        User userEntity = new User(user);
        Role roleEntity = null;
        for (Serializable role : roles) {
            try {
                roleEntity = new Role(new Long(role.toString()));
                UserRolePK PK = new UserRolePK(userEntity, roleEntity);
                UserRole userRole = new UserRole(PK);
                getHibernateTemplate().save(userRole);
            } catch (Exception e) {
                // TODO: handle exception
                log.error("setUserRoles failure! user = " + user + ", role = " + role + ", Message:" + e.getMessage());
                continue;
            }
        }
    }

    @Override
    public void removeUserRoles(Long user, Serializable... roles) {
        // TODO Auto-generated method stub
        for (Serializable role : roles) {
            try {
                executeUpdate("delete UserRole userRole where userRole.PK.user.id = ? and userRole.PK.role.id = ?", new Object[] { user, role });
            } catch (Exception e) {
                // TODO: handle exception
                log.error("removeUserRoles failure! user = " + user + ", role = " + role + ", Message:" + e.getMessage());
                continue;
            }
        }
    }

    @Override
    public boolean userNameExists(String name, Long id) {
        // TODO Auto-generated method stub
        int count = 0;
        if (id == null) {
            count = getHibernateTemplate().count("select count(*) from User user where user.name = ?", name);
        } else {
            count = getHibernateTemplate().count("select count(*) from User user where user.name = ? and user.id <> ?", new Object[] { name, id });
        }
        return count > 0;
    }

    @Override
    public boolean userEmailExists(String email, Long id) {
        // TODO Auto-generated method stub
        int count = 0;
        if (id == null) {
            count = getHibernateTemplate().count("select count(*) from User user where user.email = ?", email);
        } else {
            count = getHibernateTemplate().count("select count(*) from User user where user.email = ? and user.id <> ?", new Object[] { email, id });
        }
        return count > 0;
    }

    @Override
    public boolean userAliasExists(String alias, Long id) {
        // TODO Auto-generated method stub
        int count = 0;
        if (id == null) {
            count = getHibernateTemplate().count("select count(*) from User user where user.alias = ?", alias);
        } else {
            count = getHibernateTemplate().count("select count(*) from User user where user.alias = ? and user.id <> ?", new Object[] { alias, id });
        }
        return count > 0;
    }

    @Override
    public List<User> findUsersByRole(Long roleId) {
        // TODO Auto-generated method stub
        return list("select userRole.PK.user from UserRole userRole where userRole.PK.role.id = ?", roleId);
    }

    @Override
    public List<User> listUserLeftLikeName(String name) {
        // TODO Auto-generated method stub
        if (StringUtils.isBlank(name)) {
            return null;
        }
        EnhancedRule enhanceRule = new EnhancedRule();
        enhanceRule.add(Restrictions.like("name", name, MatchMode.START));
        enhanceRule.setPageSize(12);
        return list(enhanceRule);
    }

    @Override
    public String getNameById(Long id) {
        // TODO Auto-generated method stub
        Object obj = getHibernateTemplate().uniqueResult("select u.name from User u where u.id = ?", id);
        return obj == null ? null : obj.toString();
    }

    @Override
    public List<User> getNewRegister(int num) {
        // TODO Auto-generated method stub
        EnhancedRule enhanceRule = new EnhancedRule();
        enhanceRule.setPageSize(num);
        enhanceRule.addOrder(Order.desc("createTime"));
        return list(enhanceRule);
    }

}
